<template>
  <view class="wrap">
    <image
      class="music-player-bg"
      :src="
        musicType == 'music'
          ? 'https://ainengli.hzjrsw.com/jkhx/weight/music-bg.png'
          : 'https://ainengli.hzjrsw.com/jkhx/weight/white-noise-bg.png'
      "
      mode="scaleToFill"
    />
    <view class="player-box">
      <view class="music-type">
        <text>{{ musicType === 'music' ? '音乐' : '白噪声' }}</text>
      </view>
      <view class="music-name">
        <text>{{ musicList[musicIndex] ? musicList[musicIndex].fileName : '' }}</text>
      </view>
      <view class="music-progress-box">
        <view class="progress-box">
          <view class="progress-loading" v-if="!isCanplay">
            <up-loading-icon :size="10" />
          </view>
          <view
            class="progress-icon"
            v-else
            :style="{ left: `calc(${musicPlayer.percent}% - 8rpx)` }"
          />
          <view class="progress-bar" :style="{ width: `${musicPlayer.percent}%` }" />
        </view>
      </view>
      <view class="music-control-box">
        <view @tap="changeLoop" style="width: 130rpx">
          <image
            v-if="!musicPlayer.loop"
            class="loop-type"
            src="https://ainengli.hzjrsw.com/jkhx/common/only.png"
            mode="scaleToFill"
          />
          <image
            v-else
            class="loop-type"
            src="https://ainengli.hzjrsw.com/jkhx/common/loop.png"
            mode="scaleToFill"
          />
        </view>
        <view class="music-control">
          <view @tap="correctPre">
            <image
              class="change-icon"
              src="https://ainengli.hzjrsw.com/jkhx/common/pre-icon.png"
              mode="scaleToFill"
            />
          </view>
          <view @tap="playAudioHandle" class="play-item">
            <image
              v-show="!musicPlayer.isPlay"
              class="play-icon"
              src="https://ainengli.hzjrsw.com/jkhx/common/play-icon.png"
              mode="scaleToFill"
            />
            <image
              v-show="musicPlayer.isPlay"
              class="play-icon"
              src="https://ainengli.hzjrsw.com/jkhx/common/pause-icon.png"
              mode="scaleToFill"
            />
          </view>
          <view @tap="correctNext">
            <image
              class="change-icon"
              src="https://ainengli.hzjrsw.com/jkhx/common/next-icon.png"
              mode="scaleToFill"
            />
          </view>
        </view>
        <view class="timing" @tap="timingFun">
          <image
            class="time-type"
            src="https://ainengli.hzjrsw.com/jkhx/common/times.png"
            mode="scaleToFill"
          />
          <text class="time-name">{{
            musicPlayer.timer == 60 ? `1小时` : `${musicPlayer.timer}分钟`
          }}</text>
        </view>
      </view>
    </view>
  </view>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { onLoad, onReady, onShow, onUnload } from '@dcloudio/uni-app'
import type { mousicData, mousicListData } from '../sleepModel'
import { debounce } from '@/utils/tools'

interface playerType {
  isPlay: boolean // true-播放 false-暂停 默认false
  loop: boolean
  timer: number //定时关闭   10min 20min 1h/60min
  percent: number
  newTime: string
  totaltime: string
}

const timeList = ref<number[]>([10, 20, 60])

const musicUrl = ref<string>('')
const musicList = ref<mousicListData[]>([])
const musicType = ref<string>('')
const duration_music = ref<number>(0)
const musicIndex = ref<number>(0)
const musicPlayer = ref<playerType>({
  isPlay: false,
  loop: false,
  timer: 60,
  percent: 0,
  newTime: '00:00',
  totaltime: '00:00'
})

const timeOut = ref()
const isCanplay = ref<boolean>(false)

onLoad((option: any) => {
  isCanplay.value = false
  musicUrl.value = decodeURIComponent(option.audioUrl)
  musicList.value = JSON.parse(decodeURIComponent(option.list))
  musicType.value = option.type

  musicIndex.value = musicList.value.findIndex((item: any) => item.fileUrl == musicUrl.value)
  // console.log(musicList.value, musicIndex.value)

  musicPlayer.value = {
    isPlay: false,
    loop: false,
    timer: 60,
    percent: 0,
    newTime: '00:00',
    totaltime: '00:00'
  }

  if (timeOut.value) {
    clearTimeout(timeOut.value)
  }
})

onShow(() => {
  setTimeout(() => {
    playAudioHandle()
  }, 200)
})

let audioContext: any = null

const current = () => {
  const duration = audioContext?.duration
  // if (duration) {
  // }
  const currentTime = audioContext?.currentTime || 0
  musicPlayer.value.percent = Number(((currentTime / duration) * 100).toFixed(2))
  musicPlayer.value.newTime = times(Math.floor(currentTime))
  musicPlayer.value.totaltime = times(Math.floor(duration))
  console.log(currentTime, duration_music.value, duration)
}

const playAudioHandle = debounce(() => {
  musicPlayer.value.isPlay = !musicPlayer.value.isPlay
  if (musicPlayer.value.isPlay) {
    timeOut.value = setTimeout(() => {
      pauseAudio()
    }, musicPlayer.value.timer * 60 * 1000)
    playAudio()
  } else {
    pauseAudio()
  }
}, 300)
const playAudio = () => {
  if (audioContext && musicPlayer.value.isPlay) {
    console.warn('播放中')
    return
  } else {
    clearAudioContext()
    setTimeout(() => {
      initAudioContext()
      audioContext.src = musicUrl.value

      try {
        audioContext?.play()
        // 没有定时器时 创建定时器
        if (!timeOut.value) {
          timeOut.value = setTimeout(() => {
            pauseAudio()
          }, musicPlayer.value.timer * 60 * 1000)
        }
      } catch (error) {
        console.error('设置音频源时出错:', error)
      }
      return
    }, 100)
  }
}

const initAudioContext = () => {
  if (!audioContext) {
    isCanplay.value = false
    audioContext = uni.createInnerAudioContext()
    audioContext.loop = musicPlayer.value.loop
    audioContext.autoplay = false

    // 注册事件
    audioContext.onTimeUpdate(current)
    audioContext.onPlay(() => {
      isCanplay.value = true
      musicPlayer.value.isPlay = true
    })
    audioContext.onCanplay(() => {
      setTimeout(() => {
        isCanplay.value = true
        duration_music.value = audioContext.duration || 0
        if (musicPlayer.value.isPlay) {
          audioContext.play()
        }
      }, 100)
    })
    audioContext.onError((error) => {
      console.error('音频播放出错:', error)
    })
    audioContext.onEnded(() => {
      musicPlayer.value.percent = 100
      if (musicPlayer.value.loop) {
        audioContext.currentTime = 0
        audioContext.play()
      } else {
        nextAudio()
      }
    })
  }
}

const pauseAudio = () => {
  if (audioContext) {
    audioContext.pause()
    musicPlayer.value.isPlay = false
  }
}

const correctNext = debounce(() => {
  nextAudio()
}, 1000)

const correctPre = debounce(() => {
  prevAudio()
}, 1000)

const switchAudio = (direction: number) => {
  if (audioContext) {
    audioContext.offTimeUpdate(current)
    audioContext.offPlay()
    audioContext.offEnded()
    audioContext.destroy()
    audioContext = null
  }

  musicPlayer.value.percent = 0

  // 根据方向调整索引
  musicIndex.value += direction
  if (musicIndex.value < 0) {
    musicIndex.value = musicList.value.length - 1
  } else if (musicIndex.value >= musicList.value.length) {
    musicIndex.value = 0
  }

  musicUrl.value = musicList.value[musicIndex.value].fileUrl
  playAudio()
}

const nextAudio = () => switchAudio(1)
const prevAudio = () => switchAudio(-1)

const changeLoop = () => {
  musicPlayer.value.loop = !musicPlayer.value.loop
  if (audioContext) {
    audioContext.loop = musicPlayer.value.loop
    // 如果音频没有播放，则重新开始播放
    if (!musicPlayer.value.isPlay) {
      audioContext.currentTime = 0 // 重置播放进度
      playAudioHandle()
    }
  }
}

const timingFun = () => {
  let index = timeList.value.findIndex((item) => item === musicPlayer.value.timer)
  index++
  if (index >= timeList.value.length) {
    musicPlayer.value.timer = timeList.value[0]
  } else {
    musicPlayer.value.timer = timeList.value[index]
  }

  if (musicPlayer.value.isPlay) {
    if (timeOut.value) {
      clearTimeout(timeOut.value)
    }

    timeOut.value = setTimeout(() => {
      pauseAudio()
    }, musicPlayer.value.timer * 60 * 1000)
  }
}

const clearAudioContext = () => {
  if (audioContext) {
    audioContext.offTimeUpdate(current)
    audioContext.offPlay()
    audioContext.offEnded()
    audioContext.offCanplay()
    audioContext.offError()
    audioContext.destroy()
    audioContext = null
  }
}

onUnload(() => {
  try {
    if (audioContext) {
      audioContext.pause()
      clearAudioContext()
      musicPlayer.value.isPlay = false
    }
    if (timeOut.value) {
      clearTimeout(timeOut.value)
      timeOut.value = null
    }
  } catch (e) {
    // ...
  }
})

// 获取完整分钟数
const times = (totalSeconds: number) => {
  const minutes = Math.floor(totalSeconds / 60)
  const seconds = totalSeconds % 60
  function padTo2Digits(num: number) {
    return num.toString().padStart(2, '0')
  }
  return `${padTo2Digits(minutes)}:${padTo2Digits(seconds)}`
}
</script>
<style lang="scss" scoped>
.wrap {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

.music-player-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  vertical-align: bottom;
}

.player-box {
  position: absolute;
  bottom: 240rpx;
  left: 0;
  z-index: 100;
  width: 100%;
  height: 300rpx;
  padding: 0 48rpx;
  color: #fff;
}

.music-type {
  font-size: 48rpx;
  font-weight: 700;
  color: #fff;
}

.music-name {
  margin-top: 10rpx;
  font-size: 28rpx;
  font-weight: 400;
  color: rgb(255 255 255 / 70%);
}

.change-icon {
  width: 35rpx;
  height: 43rpx;
}

.play-item {
  width: 84rpx;
  height: 84rpx;
  margin: 0 28rpx;
}

.play-icon {
  width: 84rpx;
  height: 84rpx;
}

.music-control-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 70rpx;
}

.music-control {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 268rpx;
  height: 84rpx;
}

.loop-type {
  width: 48rpx;
  height: 48rpx;
}

.timing {
  display: flex;
  align-items: right;
  align-items: center;
  width: 130rpx;
}

.time-type {
  width: 40rpx;
  height: 40rpx;
}

.time-name {
  margin-left: 8rpx;
  font-size: 24rpx;
  font-weight: 500;
  color: #fff;
}

.music-progress-box {
  margin-top: 48rpx;

  .progress-box {
    position: relative;
    width: 100%;
    height: 6rpx;
    background: rgb(255 255 255 / 60%);
    border-radius: 6rpx;
  }

  .progress-bar {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 10;
    width: 0rpx;
    height: 6rpx;
    background: #fff;
    border-radius: 6rpx;
  }

  .progress-loading {
    position: absolute;
    top: -8rpx;
    left: -20rpx;
    z-index: 10;
    width: 10rpx;
    height: 10rpx;
  }

  .progress-icon {
    position: absolute;
    top: -5rpx;
    left: 0;
    width: 8rpx;
    height: 16rpx;
    background: #fff;
    border-radius: 2rpx;
  }
}
</style>
